package references

import (
	"jvm/nzpJvm/instructions/base"
	"jvm/nzpJvm/runtime_area"
	"jvm/nzpJvm/runtime_area/heap"
)

// 判断一个对象是不是一个类的实例。
type INSTANCE_OF struct{ base.Index16Instruction }

// instanceof 需要两个操作数，第一个是对运行时常量池的索引，可以定位到一个Class的符号引用，从字节码中获取
// 第二个是一个对象的引用，从操作数栈弹出
func (self *INSTANCE_OF) Execute(frame *runtime_area.Frame) {

	stack:= frame.OperandStack()
	// 弹出对象实例
	object := stack.PopRef()
	if object == nil {
		panic("java.lang.NullPointerException")
	}

	// 获取Class结构体
	currentMethod := frame.Method()
	currentClass := currentMethod.Class()
	constantPool := currentClass.ConstantPool()
	classRef := constantPool.GetConstant(self.Index).(*heap.ClassRef)
	// 通过符号引用解析成直接引用
	class := classRef.ResolveClass()

	// 如果对象是此Class的实例，将1压入操作数栈，否则将0压入操作数栈
	if object.IsInstanceOf(class) {
		stack.PushInt(1)
	}else {
		stack.PushInt(0)
	}
}
